package org.robert.export_client.excel.metadata;

import com.robert.common.commonutil.exception.AppException;
import lombok.EqualsAndHashCode;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.ss.usermodel.CellStyle;
import org.robert.export_client.aop.ExcelDictAdapter;
import org.robert.export_client.excel.builder.ExcelHeadBuilder;
import org.robert.export_client.excel.entity.CellStyleEntity;
import org.robert.export_client.excel.impl.ExcelWriteByDataService;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @Description
 * @Author robert
 * @Date 2024/1/20 20:52
 **/
@Slf4j
@EqualsAndHashCode(callSuper = true)
public abstract class SourceSheetBuilder extends AbstractSheetBuilder {

    protected Integer limit = 2000;


    public SourceSheetBuilder(AbstractWorkbookBuilder workbookBuilder, HSSFSheet sheet, Class<?> clazz,
                              Map<String, Map<String, String>> dictMap, Integer limit) throws Exception {
        super(workbookBuilder,sheet,clazz,dictMap);
        setLimit(limit);
    }

    public SourceSheetBuilder(AbstractWorkbookBuilder workbookBuilder, HSSFSheet sheet, Class<?> clazz,
                              Map<String, Map<String, String>> dictMap, Integer limit,  CellStyleEntity titleStyle) throws Exception {
        super(workbookBuilder,sheet,clazz,dictMap, titleStyle);
        setLimit(limit);
    }

    public void setLimit(Integer limit) {
        // 构建参数
        if (limit == null || limit == 0) {
            this.limit = 5000;
        }else{
            this.limit = limit;
        }
    }

    public void doWrite(IBaseQuery repository, Object t) throws Exception {
        this.doWrite(repository, t, null);
    }

    public void doWrite(IBaseQuery repository, Object t, CellStyleEntity entity) throws Exception {
        // 创建内容
        List<ExcelHeadEntity> headEntityList = this.excelHeadBuilder.getExcelHeadEntityList();
        // 获取内容
        Long aLong = repository.queryCount(t);
        if (aLong == null || aLong == 0) {
            throw new AppException("500", "没有数据");
        }
        int pageCount = (int) Math.ceil((double) aLong / limit);
        List<?> data = new ArrayList<>();
        // 去调用写入,使用时根据数据库分页的总的页数来
        for (int page = 1; page <= pageCount; page++) {
            int finalPage = (page - 1) * limit;
            // 分页去数据库查询数据 这里可以去数据库查询每一页的数据
            data = repository.query(t, finalPage, limit);
            writeByDataService.doWrite(data, clazz, headEntityList);
            data.clear();
        }
    }

    @Override
    public AbstractWriteSheet build(){
        this.flag = false;
        return new AbstractWriteSheet(this);
    }
    @Override
    public void finish(){
        this.flag = true;
        log.info("sheet {} write finished", sheet.getSheetName());
    }

}
